在前兩篇的實驗中,我們觀察到了一些現象,也遺留了一些問題,首先,我們知道 docker image 其實是由多層 layers 組成的,以我們自己 commit 出來的 image mynginx:a
來說,透過 docker image inspect mynginx:a
可以觀察到他有 7 層 layers,而且也確實可以在 Host 中找到那 7 個檔案夾,但當我們用這個 image 啟動一個 container,在這個 container 中並不會對這些 layer 有所感覺,用起來會像是「平」的一樣,這是怎麼做到的呢?
這裡其實是使用了一種叫做 UnionFS (聯合檔案系統) 的技術,根據 Wiki 的解釋,UnionFS 可以把多個檔案夾的內容聯合掛載到同一個目錄底下去,所以即使這些檔案夾都在不同的地方,UnionFS 也可以讓他們看起來像是「一個」文件系統。Linux 中的 UnionFS 有好幾種實作,在研究 docker 時比較常看到的可能是 AUFS (AnotherUnionFS)及 OverlayFS,想要知道 Host 上的 docker 是用哪一種,可以透過 docker info
來查看:
$ docker info
...略
Storage Driver: overlay2
...略
可以注意一下這邊出現的詞是「Storage Driver」,docker 會用 storage driver 來儲存 image layers 及 container 的可寫層,storage driver 有好幾個選擇,目前官方建議與預設的是 overlay2,這是 docker 為 OverlayFS 提供的一種 storage driver。(看到 overlay2,可以猜想到那應該有 overlay 吧,沒錯,不過 overlay2 更新與更穩定,所以條件允許的話,推薦用 overlay2 喔。)
OverlayFS 可以將多個檔案夾「聯合」起來使其看起來像是只有一個檔案夾,這些被聯合的檔案夾在 OverlayFS 中被稱為 layers(是不是很熟悉?),這整個聯合的過程稱為 union mount。除此之外,OverlayFS 會將較底層的檔案夾稱為 lowerdir
,高層的檔案夾稱為 upperdir
,而 lowerdir
與 upperdir
聯合的結果稱為 merged
,另外還有一個叫做 work
的檔案夾,這個是 OverlayFS 內部要使用的。
回想一下,在前兩篇文章中,當我們用 inspect 指令查看 image 的 GraphDriver
區塊時,除了當時我們特別觀察的 LowerDir
與 UpperDir
外,其實還有 MergedDir
跟 WorkDir
,是不是跟 OverlayFS 提到的這些名稱對應起來了呢?
到這邊,我們先跳開 docker 一下,在 Host 試試看 OverlayFS 是怎麼樣操作的。我們先來準備一下環境:
~/overlay-test$ tree
.
├── lower1
│ ├── a.txt
│ └── x.txt
├── lower2
│ ├── b.txt
│ └── x.txt
├── merged
├── upper
│ └── c.txt
└── work
5 directories, 5 files
$ cat lower1/x.txt
A
$ cat lower2/x.txt
B
接著我們執行 mount
指令:
$ sudo mount -t overlay overlay -o lowerdir=lower1:lower2,upperdir=upper,workdir=work merged
# 確認一下:
$ cat /proc/mounts | grep overlay
overlay /home/ubuntu/overlay-test/merged overlay rw,relatime,lowerdir=lower1:lower2,upperdir=upper,workdir=work 0 0
檢查一下 merged 檔案夾:
~/overlay-test$ tree
.
├── lower1
│ ├── a.txt
│ └── x.txt
├── lower2
│ ├── b.txt
│ └── x.txt
├── merged
│ ├── a.txt
│ ├── b.txt
│ ├── c.txt
│ └── x.txt
├── upper
│ └── c.txt
└── work
└── work [error opening dir]
6 directories, 9 files
$ cat merged/x.txt
A
可以看到 a, b, c, x 四個檔案都出現在 merged 裡了,且 x.txt 的內容是 A,也就是來自 lower1 裡的 a.txt,這是因為 OverlayFS 是用 layer 的方式堆疊,且上層的 layer 可以蓋掉下層的 layer。
用圖形說明的話,大概就是這個樣子:
到這裡,我們已經手動用 overlay 這種方式作出聯合目錄了,之後再讓我們來對 merged 中的檔案做點其他的測試吧!